package search;
import java.io.File;
import java.io.IOException;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;



public class Searcher {

	private final int HITS_PER_PAGE = 20;
	private String indexPath = "";

	public String getIdxPath() {
		return indexPath;
	}

	public void setIdxPath(String indexPath) {
		this.indexPath = indexPath;
	}

	private IndexSearcher idxSearcher;
	private IndexReader idxReader;
	private Directory idxDir;

	public Searcher(String indexPath) throws CorruptIndexException,
			IOException {
		this.indexPath = indexPath;
		idxDir = FSDirectory.open(new File(indexPath));
		if (IndexReader.indexExists(idxDir)) {
			idxReader = IndexReader.open(idxDir);
			idxSearcher = new IndexSearcher(idxReader);
		}
	}

	public SearchResult searchById(long id) throws IOException,
			ParseException {
		Document doc = findDocumentById(id);
		SearchResult result = new SearchResult();
		if (doc != null) {
			result.getHits().add(
					new FoundItem(Long.parseLong(doc
							.get(SearchableIndexer.ID_FIELD)), doc
							.get(SearchableIndexer.NAME_FIELD),
							doc.get(SearchableIndexer.DESCRIPTION_FIELD)));
			return result;
		}
		return result;
	}

	public Document findDocumentById(long id) throws IOException,
			ParseException {
		if (IndexReader.indexExists(idxDir)) {
			QueryParser parser = new QueryParser(Version.LUCENE_36,
					SearchableIndexer.ID_FIELD, new StandardAnalyzer(
							Version.LUCENE_36));

			TopDocs topDocs = idxSearcher.search(
					parser.parse(Long.toString(id)), 1);
			if (topDocs.totalHits > 0) {
				return idxSearcher.doc(topDocs.scoreDocs[0].doc);
			}
		}
		return null;
	}

	public SearchResult search(String tag, int pageNum)
			throws IOException, ParseException {
		SearchResult result = new SearchResult();
		if (IndexReader.indexExists(idxDir)) {
			//Term tagTerm = new Term(SearchableIndexer.TAG_FIELD, tag + "*");
			//Query wQ = new WildcardQuery(tagTerm);
			QueryParser parser = new QueryParser(Version.LUCENE_36,
					SearchableIndexer.TAG_FIELD, new StandardAnalyzer(
							Version.LUCENE_36));
			Query wQ = parser.parse(tag + "*");
					
			TopDocs topDocs = idxSearcher.search(wQ, HITS_PER_PAGE * pageNum);
			result.setHitTotal(topDocs.totalHits);
			for (int i = 0; i < topDocs.totalHits; i++) {
				if ((pageNum - 1) * HITS_PER_PAGE <= i
						&& i < pageNum * HITS_PER_PAGE) {
					Document doc = idxSearcher.doc(topDocs.scoreDocs[i].doc);
					FoundItem found = new FoundItem(Long.parseLong(doc
							.get(SearchableIndexer.ID_FIELD)),
							doc.get(SearchableIndexer.NAME_FIELD),
							doc.get(SearchableIndexer.DESCRIPTION_FIELD));
					result.getHits().add(found);
				}
			}
		}
		return result;
	}

	public void endSearch() throws IOException {
		idxSearcher.close();
		idxReader.close();
	}

	@Override
	protected void finalize() throws Throwable {
		endSearch();
	}

}
